import React from "react";
import { useRoutes, RouteObject } from "react-router-dom";
import localStorage from "store2";

import PageLoading from "./components/PageLoading";

const { createContext, useState } = React;

function loadableComp(LazyComponent: any) {
  return (): JSX.Element => (
    <React.Suspense fallback={<PageLoading />}>
      <LazyComponent />
    </React.Suspense>
  );
}

const AppLayout = loadableComp(
  React.lazy(() => import("./components/AppLayout"))
);

const NoMatch = loadableComp(React.lazy(() => import("./components/NoMatch")));

const Login = loadableComp(React.lazy(() => import("./views/Other/Login")));

const SignUp = loadableComp(
  React.lazy(() => import("./views/Other/UserInfo/SignUp"))
);

const Detail = loadableComp(
  React.lazy(() => import("./views/Other/UserInfo/Detail"))
);

const Modify = loadableComp(
  React.lazy(() => import("./views/Other/UserInfo/Modify"))
);

const ModifyPassword = loadableComp(
  React.lazy(() => import("./views/Other/UserInfo/ModifyPassword"))
);

const Entity = loadableComp(React.lazy(() => import("./views/Entity")));

const EntityForm = loadableComp(
  React.lazy(() => import("./views/Entity/EntityForm"))
);

const Storage = loadableComp(React.lazy(() => import("./views/Storage")));

export interface UserInfoType {
  username: string;
  email: string;
  avatar: string;
  _id: string;
}

interface UserInfoContextType {
  userInfo: UserInfoType;
  setUserInfo: (userInfo: object) => void;
}

const userInfoContextDefaultValues: UserInfoContextType = {
  userInfo: {} as UserInfoType,
  setUserInfo: () => {},
};
export const UserInfoContext = createContext(userInfoContextDefaultValues);

export default function App() {
  const routes: RouteObject[] = [
    {
      path: "/",
      element: <AppLayout />,
      children: [
        { index: true, element: <Entity /> },

        { path: "/entity", element: <Entity /> },
        { path: "/entity/form", element: <EntityForm /> },
        { path: "/storage", element: <Storage /> },
        { path: "/login", element: <Login /> },
        { path: "/signUp", element: <SignUp /> },
        { path: "/detail", element: <Detail /> },
        { path: "/modify", element: <Modify /> },
        { path: "/modifyPassword", element: <ModifyPassword /> },
        { path: "*", element: <NoMatch /> },
      ],
    },
  ];
  const element = useRoutes(routes);

  const [userInfo, setUserInfo] = useState(localStorage.get("userInfo") || {});
  const userInfoDefaultValue: UserInfoContextType = { userInfo, setUserInfo };

  return (
    <UserInfoContext.Provider value={userInfoDefaultValue}>
      {element}
    </UserInfoContext.Provider>
  );
}
